package api

import (
	"bytes"
	"fmt"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
	jsoniter "github.com/json-iterator/go"
	"github.com/xuri/excelize/v2"
	"zhonghui/console/service"
	"zhonghui/console/structs"
	"zhonghui/console/warehouse/dbx/cache_main"
	"zhonghui/console/warehouse/dbx/db_zh_kernel"
	"zhonghui/console/warehouse/helperx"
	"zhonghui/console/warehouse/modelx/model_zh_kernel"
	"zhonghui/console/warehouse/respx"
	"zhonghui/console/warehouse/servicex"
)

func (server *Server) TaskCharts(c *gin.Context) {
	id, _ := strconv.Atoi(c.Param("id"))
	// id = 22

	// 查询任务
	task := model_zh_kernel.SysTask{}
	if err := db_zh_kernel.ClientCtx(c).Where("id = ?", id).Take(&task).Error; err != nil {
		respx.Error(c, "无法找到该任务", err)
		return
	}

	// 临时的进度数据
	tmpProgress := service.GetTaskTempProgress(task.ID)
	tmpProgressFail := service.GetTaskTempProgressFail(task.ID)

	resp := structs.TaskChartsResp{
		Count: task.Count,
	}

	// 进度
	if task.Status == structs.TaskStatusProcessing || task.Status == structs.TaskStatusPaused {
		resp.CountSuccess = tmpProgress
		resp.CountFail = tmpProgressFail
	} else {
		resp.CountSuccess = task.CountSuccess
		resp.CountFail = task.CountFail
	}
	resp.Progress = uint64((float64(resp.CountSuccess+resp.CountFail) / float64(task.Count)) * 100)

	if resp.Count > 0 {
		resp.FailRate = helperx.NiceRate(float64(resp.CountFail) / float64(resp.Count))
	} else {
		resp.FailRate = "0%"
	}

	// 点击数据
	resp.ClickCharts = service.GetClickDataForTask(&task)
	if resp.CountSuccess > 0 {
		resp.ClickCharts.ClickRate = helperx.NiceRate(float64(resp.ClickCharts.Total) / float64(resp.CountSuccess))
	} else {
		resp.ClickCharts.ClickRate = "0%"
	}

	// 小程序数据
	resp.MpCharts = service.GetMpDataForTask(&task)
	if resp.ClickCharts.Total > 0 {
		resp.MpCharts.MpRate = helperx.NiceRate(float64(resp.MpCharts.Total) / float64(resp.ClickCharts.Total))
	} else {
		resp.MpCharts.MpRate = "0%"
	}

	// 企微数据
	resp.WeComCharts = service.GetWeComDataForTask(&task)
	if resp.MpCharts.Total > 0 {
		resp.WeComCharts.WeComRate = helperx.NiceRate(float64(resp.WeComCharts.Total) / float64(resp.MpCharts.Total))
	} else {
		resp.WeComCharts.WeComRate = "0%"
	}

	// 投保成功页面访问
	resp.InsurancePolicyCharts = service.GetInsurancePolicyDataForTask(&task)
	if resp.ClickCharts.Total > 0 {
		resp.InsurancePolicyCharts.PolicyRate = helperx.NiceRate(float64(resp.InsurancePolicyCharts.Total) / float64(resp.ClickCharts.Total))
	} else {
		resp.InsurancePolicyCharts.PolicyRate = "0%"
	}

	// 升级成功页面访问
	resp.InsurancePolicyUpgradeCharts = service.GetInsurancePolicyUpgradeDataForTask(&task)
	if resp.ClickCharts.Total > 0 {
		resp.InsurancePolicyUpgradeCharts.PolicyRate = helperx.NiceRate(float64(resp.InsurancePolicyUpgradeCharts.Total) / float64(resp.ClickCharts.Total))
	} else {
		resp.InsurancePolicyUpgradeCharts.PolicyRate = "0%"
	}

	// 一些假数据
	visitArr := `[{"key": "2023-02-15","value": 7},{"key": "2023-02-16","value": 5},{"key": "2023-02-17","value": 4},{"key": "2023-02-18","value": 2},{"key": "2023-02-19","value": 4},{"key": "2023-02-20","value": 7},{"key": "2023-02-21","value": 5},{"key": "2023-02-22","value": 6},{"key": "2023-02-23","value": 5},{"key": "2023-02-24","value": 9},{"key": "2023-02-25","value": 6},{"key": "2023-02-26","value": 3},{"key": "2023-02-27","value": 1},{"key": "2023-02-28","value": 5},{"key": "2023-03-01","value": 3},{"key": "2023-03-02","value": 6},{"key": "2023-03-03","value": 5}]`
	visitList := make([]structs.ChartsKV, 0)
	_ = jsoniter.UnmarshalFromString(visitArr, &visitList)
	resp.VisitData = visitList

	respx.Success(c, resp, nil)
}

func (server *Server) TaskChartsDownload(c *gin.Context) {
	allData := make([]structs.TaskChartsDownload, 0)
	cacheData := cache_main.Client().Get(c, "charts_download_cache").Val()
	if cacheData == "" {
		respx.Alert(c, "暂无数据，请等待后台生成")
		return
	}
	_ = jsoniter.UnmarshalFromString(cacheData, &allData)

	f := excelize.NewFile()
	defer func() {
		if err := f.Close(); err != nil {
			fmt.Println(err)
		}
	}()
	index, err := f.NewSheet("Sheet1")
	if err != nil {
		fmt.Println(err)
		return
	}

	// 设置字段
	f.SetCellValue("Sheet1", "A1", "任务ID")
	f.SetCellValue("Sheet1", "B1", "任务名")
	f.SetCellValue("Sheet1", "C1", "任务总量")
	f.SetCellValue("Sheet1", "D1", "模板ID")
	f.SetCellValue("Sheet1", "E1", "模板内容")
	f.SetCellValue("Sheet1", "F1", "创建时间")
	f.SetCellValue("Sheet1", "G1", "完成时间")
	f.SetCellValue("Sheet1", "H1", "点击总量")
	f.SetCellValue("Sheet1", "I1", "点击率")
	f.SetCellValue("Sheet1", "J1", "投保总量")
	f.SetCellValue("Sheet1", "K1", "投保率")
	f.SetCellValue("Sheet1", "L1", "小程序总量")
	f.SetCellValue("Sheet1", "M1", "小程序率")
	f.SetCellValue("Sheet1", "N1", "企微总量")
	f.SetCellValue("Sheet1", "O1", "企微率")

	i := 2
	for _, d := range allData {
		f.SetCellValue("Sheet1", fmt.Sprintf("A%d", i), d.Task.ID)
		f.SetCellValue("Sheet1", fmt.Sprintf("B%d", i), d.Task.Title)
		f.SetCellValue("Sheet1", fmt.Sprintf("C%d", i), d.Task.CountSuccess)
		f.SetCellValue("Sheet1", fmt.Sprintf("D%d", i), d.Task.SmsTemplate)
		f.SetCellValue("Sheet1", fmt.Sprintf("E%d", i), d.Tp.Content)
		f.SetCellValue("Sheet1", fmt.Sprintf("F%d", i), d.Task.CreateTime.Format(helperx.TimeLayoutCommon))
		f.SetCellValue("Sheet1", fmt.Sprintf("G%d", i), d.Task.UpdateTime.Format(helperx.TimeLayoutCommon))
		f.SetCellValue("Sheet1", fmt.Sprintf("H%d", i), d.ClickCharts.Total)
		f.SetCellValue("Sheet1", fmt.Sprintf("I%d", i), d.ClickCharts.ClickRate)
		f.SetCellValue("Sheet1", fmt.Sprintf("J%d", i), d.InsurancePolicyCharts.Total)
		f.SetCellValue("Sheet1", fmt.Sprintf("K%d", i), d.InsurancePolicyCharts.PolicyRate)
		f.SetCellValue("Sheet1", fmt.Sprintf("L%d", i), d.MpCharts.Total)
		f.SetCellValue("Sheet1", fmt.Sprintf("M%d", i), d.MpCharts.MpRate)
		f.SetCellValue("Sheet1", fmt.Sprintf("N%d", i), d.WeComCharts.Total)
		f.SetCellValue("Sheet1", fmt.Sprintf("O%d", i), d.WeComCharts.WeComRate)
		i++
	}

	f.SetActiveSheet(index)

	// 将Excel文件保存到内存缓冲区中
	buf := new(bytes.Buffer)
	if err := f.Write(buf); err != nil {
		respx.Alert(c, "导出失败")
		return
	}

	path := fmt.Sprintf("zhonghui/export/%s/data_%d.xlsx", helperx.TimeLayoutUYmd, time.Now().UnixNano())

	oc, _ := servicex.OssClient("normal")
	oc.OssPutBucketExtend(path, buf, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")

	u, _ := oc.OssFullPath(path, true)

	respx.Success(c, gin.H{"url": u.Origin}, nil)
}
